package sfeir.ergosum;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import sfeir.ergosum.dao.DatabaseConnection;
import sfeir.ergosum.dao.DatabaseProvider;
import sfeir.ergosum.dao.RemoteProvider;
import sfeir.ergosum.menu.MenuService;
import sfeir.ergosum.model.Contact;
import sfeir.ergosum.model.Group;
import sfeir.ergosum.model.LetterIndex;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.widget.Toast;

import com.sfeir.proto.hivelayout.HiveScrolledView;

public class HiveActivity extends Activity {

    public final static int DIALOG_ADD_GROUP = 12;
    public final static int DIALOG_RENAME_GROUP = 13;
    public final static int DIALOG_RENAME_CONTACT = 14;
    public final static int DIALOG_MOVE_CONTACT = 15;
    public final static int DIALOG_PROGRESS = 16;
    private ProgressDialog mProgressDialog;

    private HiveScrolledView hsv;

    private Thread mThread;
    private Handler mHandler = new Handler();

    final Runnable invalidContact = new Runnable() {
        public void run() {
            Toast.makeText(HiveActivity.this,
                    getString(R.string.contact_invalid), 10000).show();
        }
    };
    final Runnable validContact = new Runnable() {
        public void run() {
            // startActivity(HiveActivity.this, "", "");
            onResume();
        }
    };

    final Runnable setupHiveView = new Runnable() {
        public void run() {
            hsv.getHv().setupNewCells();
        }
    };

    final Runnable setupAllHiveView = new Runnable() {
        public void run() {
            hsv.getHv().setupAll();
        }
    };

    public HiveScrolledView getHsv() {
        return this.hsv;
    }

    public void setHsv(HiveScrolledView hsv) {
        this.hsv = hsv;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        long startTime = new Date().getTime();
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        final long[] group = getIntent().getLongArrayExtra("group");
        final Group fixGroup = (Group) getIntent().getSerializableExtra(
                "FixGroup");
        final LetterIndex letter = (LetterIndex) getIntent()
                .getSerializableExtra("letter");
        final int level = getIntent().getIntExtra("level", 0);
        final Boolean actionPhone = getIntent().getBooleanExtra("actionPhone", true);

        final DatabaseProvider dp = new DatabaseProvider(
                new DatabaseConnection(this));

        if (letter != null) {
            Log.e("LETTER", "LETTER");
            hsv = new HiveScrolledView(this);
            hsv.getHv().setStatusBelowTitle(letter.getLetter());

            Thread contactThread = new Thread() {

                public void run() {
                    Looper.prepare();
                    boolean actionPhone = true;

                    dp.open();
                    List<Contact> allLightContacts = new ArrayList<Contact>();
                    switch (letter.getType()) {
                    case LetterIndex.TYPE_ROOT:
                        Log.w("TYPE", "ROOT");
                        allLightContacts = dp
                                .getAllLightContactsFromLetterIndex(letter
                                        .getId());
                        break;

                    case LetterIndex.TYPE_PHONE:
                        Log.w("TYPE", "PHONE");
                        allLightContacts = dp
                                .getAllLightContactsFromPhoneIndex(letter
                                        .getId());
                        break;

                    case LetterIndex.TYPE_SMS:
                        Log.w("TYPE", "SMS");
                        allLightContacts = dp
                                .getAllLightContactsFromPhoneIndex(letter
                                        .getId());
                        hsv.getHv().setActionPhone(false);
                        actionPhone = false;
                        break;

                    case LetterIndex.TYPE_MAIL:
                        Log.w("TYPE", "MAIL");
                        allLightContacts = dp
                                .getAllLightContactsFromMailIndex(letter
                                        .getId());
                        break;

                    default:
                        break;
                    }

                    dp.close();

                    for (Contact c : allLightContacts) {
                        hsv.getHv().addContactCell(c);
                        mHandler.post(setupHiveView);
                    }

                    if (allLightContacts.size() > 1)
                        for (Group g : getFilters(allLightContacts, level)) {
                            g.setName(letter.getLetter() + g);
                            hsv.getHv().addDynaGroupCell(g, level, actionPhone);
                        }

                    do {

                    } while (!hsv.getHv().isConstantsOk());
                    mHandler.post(setupAllHiveView);
                    Looper.loop();

                }
            };
            contactThread.start();

            setContentView(hsv);

        } else if (group != null || fixGroup != null) {

            hsv = new HiveScrolledView(this);
            final String title = getIntent().getStringExtra("title");
            hsv.getHv().setStatusBelowTitle(title);

            if (fixGroup != null
                    && (fixGroup.getId() == -2 || fixGroup.getId() == -3 || fixGroup.getId() == -4)) {
                Log.e("GROUP", "SMS");
                hsv.getHv().setMinCellSize(40);

                Thread contactThread = new Thread() {

                    public void run() {
                        Looper.prepare();

                        boolean actionPhone = true;
                        List<LetterIndex> indexes;
                        dp.open();
                        if (fixGroup.getId() == -2)
                            indexes = dp.getAllPhoneIndexes();
                        else if (fixGroup.getId() == -4) {
                            indexes = dp.getAllPhoneIndexes();
                            actionPhone = false;
                        } else
                            indexes = dp.getAllMailIndexes();
                        dp.close();
                        
                        int max = 0;
                        for (LetterIndex li : indexes) {
                            if (li.getOccu() > max)
                                max = li.getOccu();
                        }

                        for (LetterIndex li : indexes) {
                            if (!actionPhone)
                                li.setType(LetterIndex.TYPE_SMS);
                            hsv.getHv().addLetterCell(li,max);
                        }

                        mHandler.post(setupAllHiveView);
                        Looper.loop();
                    }
                };
                contactThread.start();
            } else {
                Log.e("GROUP", "GROUP");
                Thread contactThread = new Thread() {

                    public void run() {
                        Looper.prepare();

                        List<Contact> allLightContacts;
                        dp.open();
                        if (group != null) {
                            allLightContacts = dp
                                    .getAllLightContactsFromTable(group);
                        } else {
                            allLightContacts = dp
                                    .getAllLightContactsFromGroup(fixGroup
                                            .getId());
                            Log.e("fixgroup", ""+fixGroup.getId());

                        }
                        dp.close();

                        for (Contact c : allLightContacts) {
                            if(!actionPhone)
                                hsv.getHv().setActionPhone(false);
                            hsv.getHv().addContactCell(c);
                            mHandler.post(setupHiveView);
                        }

                        if (allLightContacts.size() > 1)
                            for (Group g : getFilters(allLightContacts, level)) {
                                if (level > 0)
                                    g.setName(title + g.getName());
                                hsv.getHv().addDynaGroupCell(g, level, actionPhone);
                            }

                        mHandler.post(setupAllHiveView);
                        Looper.loop();
                    }
                };
                contactThread.start();

            }

            setContentView(hsv);

        }

        long stopTime = new Date().getTime();
        Log.w("HiveActivity.onCreate execution time", ""
                + (stopTime - startTime));
    }

    @Override
    public void onResume() {
        long startTime = new Date().getTime();

        super.onResume();

        final long[] group = getIntent().getLongArrayExtra("group");
        final Group fixGroup = (Group) getIntent().getSerializableExtra("FixGroup");
        final LetterIndex letter = (LetterIndex) getIntent().getSerializableExtra("letter");

        if (fixGroup == null && group == null && letter == null) {

            hsv = new HiveScrolledView(this);
            hsv.getHv().setMinCellSize(40);
            hsv.getHv().setStatusBelowTitle("Index");

            final DatabaseProvider dp = new DatabaseProvider(
                    new DatabaseConnection(this));

            Thread contactThread = new Thread() {

                public void run() {
                    Looper.prepare();

                    dp.open();
                    List<LetterIndex> indexes = dp.getAllLetterIndexes();
                    List<Group> groups = dp.getAllGroups();
                    groups.remove(groups.size() - 1);
                    dp.close();

                    int max = 0;
                    for (LetterIndex li : indexes) {
                        if (li.getOccu() > max)
                            max = li.getOccu();
                    }

                    for (LetterIndex li : indexes) {
                        hsv.getHv().addLetterCell(li, max);
                    }

                    for (Group g : groups) {
                        dp.open();
                        hsv.getHv().addFixedGroupCell(g, true);
                    }

                    Group gMail = new Group("Mail");
                    gMail.setId(-3);
                    hsv.getHv().addFixedGroupCell(gMail, false);

                    Group gPhone = new Group("Phone");
                    gPhone.setId(-2);
                    hsv.getHv().addFixedGroupCell(gPhone, false);

                    Group gSms = new Group("Sms");
                    gSms.setId(-4);
                    hsv.getHv().addFixedGroupCell(gSms, false);

                    do {

                    } while (!hsv.getHv().isConstantsOk());
                    mHandler.post(setupAllHiveView);
                    Looper.loop();
                }
            };
            contactThread.start();

            setContentView(hsv);
        }

        long stopTime = new Date().getTime();
        Log.w("HiveActivity.onResume execution time", ""
                + (stopTime - startTime));

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return MenuService.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        return MenuService.onMenuItemSelected(this, item);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == MenuService.REFRESH) {
            if (resultCode == RESULT_OK) {
                startActivity(this, "", "");
            }
        }
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
        case DIALOG_PROGRESS:
            mProgressDialog = new ProgressDialog(this);
            mProgressDialog.setTitle(R.string.add_contact_wait_url);
            mProgressDialog.setIndeterminate(true);
            mProgressDialog.setButton2(getText(R.string.dialog_cancel),
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog,
                                int whichButton) {

                            mThread.stop();
                            mProgressDialog.dismiss();
                            /* User clicked No so do some stuff */
                        }
                    });
            return mProgressDialog;
        }
        return null;
    }

    @Override
    protected void onStart() {
        long startTime = new Date().getTime();
        super.onStart();
        if (getIntent().hasExtra("code")) {
            Intent intent = getIntent();

            final String key = intent.getStringExtra("code");
            final String alias = intent.getStringExtra("alias");
            showDialog(DIALOG_PROGRESS);
            /* User clicked OK so do some stuff */
            mThread = new Thread() {
                public void run() {
                    RemoteProvider dao = new RemoteProvider(
                            new DatabaseConnection(HiveActivity.this));
                    if (dao.addContact(key, alias) == null) {
                        mProgressDialog.dismiss();
                        mHandler.post(invalidContact);
                    } else {
                        mProgressDialog.dismiss();
                        mHandler.post(validContact);
                    }
                }
            };
            mThread.start();

            intent.removeExtra("code");
            intent.removeExtra("alias");
        }
        long stopTime = new Date().getTime();
        Log.w("HiveActivity.onStart execution time", ""
                + (stopTime - startTime));
    }

    private List<Group> getFilters(List<Contact> contacts, int level) {
        long startTime = new Date().getTime();
        HashMap<String, Group> allFiltersMap = new HashMap<String, Group>();
        List<Group> allFilters = new ArrayList<Group>();

        for (Contact c : contacts) {
            String name = c.getPerson().getName().toUpperCase();
            if (name.length() >= level + 1) {
                String s = name.substring(level, level + 1);
                if (allFiltersMap.containsKey(s)) {
                    allFiltersMap.get(s).addContact(c);
                } else {
                    Group g = new Group(s);
                    g.addContact(c);
                    allFiltersMap.put(s, g);
                }
            }
        }
        for(Group g: allFiltersMap.values()) {
            allFilters.add(g);
        }

        Collections.sort(allFilters, new Comparator<Group>() {
            @Override
            public int compare(Group object1, Group object2) {
                return -object1.getName().toUpperCase().compareTo(
                        object2.getName().toUpperCase());
            }
        });

        long stopTime = new Date().getTime();
        Log.w("ContactHiveAdapter.getFilters execution time",""+(stopTime-startTime));
        return allFilters;
    }

    public static void startActivity(Context context, String code, String alias) {
        Intent i = new Intent(context, HiveActivity.class);
        if (code.trim().length() != 0) {
            i.putExtra("code", code);
            i.putExtra("alias", alias);
        }
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        context.startActivity(i);
    }
}
